package yb.ecp.fast.user.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.user.dao.entity.AccountLoginRecordDO;
import yb.ecp.fast.user.dao.mapper.AccountLoginRecordMapper;
import yb.ecp.fast.user.feign.IpFeignClient;
import yb.ecp.fast.user.infra.ErrorCode;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class AsyncService {


    @Autowired
    AccountLoginRecordMapper accountLoginRecordMapper;
    @Autowired
    private IpFeignClient ipFeignClient;

    @Async
    public void recordUserLoginRecord(HttpServletRequest request, String userId, String loginName, String userName, String spaceId) {
        try {
            String ipAddr = getIpAddr(request);
            AccountLoginRecordDO recordDO = new AccountLoginRecordDO();
            recordDO.setLoginIp(ipAddr);
            recordDO.setLoginTime(new Date());
            recordDO.setUserId(userId);
            recordDO.setUserLoginName(loginName);
            recordDO.setSpaceId(spaceId);
            recordDO.setUserName(userName);
            accountLoginRecordMapper.insert(recordDO);
            updateLoginIpBelong(ipAddr, recordDO.getId());
        } catch (Exception e) {
            LogHelper.error("保存用户登录记录失败" + e, ErrorCode.SqlSyntaxError.getCode());
        }
    }

    private void updateLoginIpBelong(String ip, String id) {
        LogHelper.monitor("更新id=" + id + "的ip=" + ip + "的归属地");
        if (StringUtils.isEmpty(id)) {
            LogHelper.monitor("更新用户登录记录ip归属时校验id为空");
        }
        if (StringUtils.isEmpty(ip)) {
            LogHelper.monitor("更新用户登录记录ip归属时校验ip为空");
        }
        //ip归属地
        String ipAttribution = getIpAttribution(ip);
        if (StringUtils.isEmpty(ipAttribution)) {
            return;
        }
        //根据id更新ip的归属
        accountLoginRecordMapper.updateIpBelong(id, ipAttribution);
    }

    //获取ip的归属地
    private String getIpAttribution(String ip) {
        AccountLoginRecordDO hasIpBelongRecord = accountLoginRecordMapper.selectOneHasIpBelong(ip);
        if (hasIpBelongRecord != null) {
            hasIpBelongRecord.getIpHome();
        }
        try {
            Map ipAttributionMap = ipFeignClient.getIpAttribution(ip);
            if (ipAttributionMap == null) {
                return null;
            }
            Object statusObj = ipAttributionMap.get("status");
            if (statusObj == null) {
                return null;
            }
            String status = (String) statusObj;
            if (StringUtils.isEmpty(status) || !status.equals("0")) {
                return null;
            }
            Object dataLstOjb = ipAttributionMap.get("data");
            if (dataLstOjb == null) {
                return null;
            }
            List dataLst = (List) dataLstOjb;
            if (CollectionUtils.isEmpty(dataLst)) {
                return null;
            }
            Map data = (Map) dataLst.get(0);
            Object locationObj = data.get("location");
            if (locationObj == null) {
                return null;
            }
            String location = (String) locationObj;
            if (StringUtils.isEmpty(location)) {
                return null;
            }
            return location;
        } catch (Exception e) {
            LogHelper.error("更新用户登录记录ip归属失败" + e, ErrorCode.SqlSyntaxError.getCode());
        }
        return null;
    }

    private String getIpAddr(HttpServletRequest request) {
        try {
            String ip = request.getHeader("x-forwarded-for");
            if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
                // 多次反向代理后会有多个ip值，第一个ip才是真实ip
                if (ip.indexOf(",") != -1) {
                    ip = ip.split(",")[0];
                }
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("X-Real-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            return ip;
        } catch (Exception e) {
            LogHelper.error("获取用户的ip出现异常" + e, ErrorCode.Failure.getCode());
        }
        LogHelper.error("未获取到ip", ErrorCode.Failure.getCode());
        return null;
    }
}
